<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>飞机大战</title>
</head>
<body>
<div id="stage" style="width: 480px;height: 650px;margin: 0px auto;">
    <canvas id="canvas" width="480px" height="650px"></canvas>
</div>
<script>
    //定义宽和高
    var WIDTH=480,HEIGHT=650;
    var score=0,life=3;
    //定义状态
    var START= 0,
            STARTING= 1,
            RUNNING= 2,
            PAUSE= 3,
            GAME_OVER=4;
    /**
     *state表示游戏的状态
     */
    var state=START;

    //获取数据
    var canvas=document.getElementById("canvas");
    ctx=canvas.getContext("2d");

    /***
     * 创建图像对象用来表示天空,英雄,敌人,版权
     */
    var bg=new Image();
    bg.src="img/background.png";

    var copyright=new Image();
    copyright.src="img/shoot_copyright.png";

    var pause=new Image();
    pause.src="img/game_pause_nor.png";

    var l = [];
    l[0] = new Image();
    l[0].src="img/game_loading1.png";
    l[1] = new Image();
    l[1].src="img/game_loading2.png";
    l[2] = new Image();
    l[2].src="img/game_loading3.png";
    l[3] = new Image();
    l[3].src="img/game_loading4.png";
    //创建英雄图像数组
    var h = [];
    h[0] = new Image();
    h[0].src="img/hero1.png";
    h[1] = new Image();
    h[1].src="img/hero2.png";
    h[2] = new Image();
    h[2].src="img/hero_blowup_n1.png";
    h[3] = new Image();
    h[3].src="img/hero_blowup_n2.png";
    h[4] = new Image();
    h[4].src="img/hero_blowup_n3.png";
    h[5] = new Image();
    h[5].src="img/hero_blowup_n4.png";
    //创建子弹图像
    var b = new Image();
    b.src="img/bullet1.png";

    //保存有hero发射的所有子弹
    var bullets=[];
    //为canvas添加事件(onclick ,onmousemove,onmouseout)
    canvas.onclick=function(){
        if(state==START)
            state=STARTING;
    }

    /**
     * 鼠标移动事件 处理hero与鼠标的位置
     * */
    canvas.onmousemove=function(e){
        var x= e.offsetX;
        var y= e.offsetY;

        hero.x=x-HERO.width/2;
        hero.y=y-HERO.height/2;

    }
    canvas.onmouseout=function(e){
        if(state==RUNNING)
        {
            state=PAUSE;
        }
    }

    canvas.onmouseover=function(e){
        if(state==PAUSE){
            state=RUNNING;
        }
    }

    //数据对象
    var SKY={image:bg,width:480,height:650,speed:20}; //50ms
    var LOADING={frames:l,width:186,height:38,x:0,y:HEIGHT-38,speed:5}; //200ms
    //刷新频率越快，捕获鼠标坐标的延迟就越小，鼠标与飞机同步移动的卡顿越小
    var HERO={frames:h,baseFrameCount:2,width:99,height:124,speed:100}; //10ms
    var BULLET={image:b,width:9,height:21};

    //业务对象
    /**
     * 子弹对象
     */

    var Bullet=function(config,x,y){
        this.width=config.width;
        this.height=config.height;
        this.frame=config.image;
        this.x=x;
        this.y=y;

//        this.move=function(){
//            this.y-=2;
//        }
//        this.paint=function(){
//            ctx.drawImage(this.frame,this.x,this.y);
//        }
    }
    Bullet.prototype.move=function(){
        this.y-=2;
    }
    Bullet.prototype.paint=function(){
        ctx.drawImage(this.frame,this.x,this.y);
    }
    /*
     *
     * 创建飞机业务对象
     */

    var Hero=function(config){
        this.frames=config.frames;
        this.frameIndex=0;
        this.baseFrameCount=config.baseFrameCount;
        this.width=config.width;
        this.height=config.height;
        this.speed=1000/config.speed;
        this.lastTime=0;
        this.x=(WIDTH-this.width)/2;
        this.y=HEIGHT-this.height-30;

        this.shootLastTime=0;
        //发送子弹的间隔 数字
        this.shootInterval=200;

    }
    Hero.prototype.step=function(){
        var currentTime=new Date().getTime();
        if(currentTime-this.lastTime>=this.speed){
            this.frame=this.frames[this.frameIndex%this.baseFrameCount];
            this.frameIndex++;
            this.lastTime=new Date().getTime();
        }
    }
    Hero.prototype.paint=function(){
        ctx.drawImage(this.frame,this.x,this.y);
    }
    //处理子弹的发射
    Hero.prototype.shoot=function(){
        var currentTime=new Date().getTime();
        if(currentTime-this.shootLastTime>=this.shootInterval){
            //到达时间间隔，可以发射子弹
            var bullet=new Bullet(BULLET,this.x+45,this.y);
            //数组的下标从0开始，此时长度为1，所以数组的长度永远会比下标多1
            //bullets[bullets.length]永远会自增1；
            if(bullets.length>=50)
            {
                //注释：请注意，splice() 方法与 slice() 方法的作用是不同的，splice() 方法会直接对数组进行修改。

                //slice() 方法可从已有的数组中返回选定的元素。
                //http://www.w3school.com.cn/jsref/jsref_slice_array.asp
                // bullets.slice(0,25);
                //  bullets.length=25;

                //splice() 方法向/从数组中添加/删除项目，然后返回被删除的项目。
               // 注释：该方法会改变原始数组。
                //http://www.w3school.com.cn/jsref/jsref_splice.asp
                bullets.splice(0,25);
            }
            bullets[bullets.length]=bullet;
            console.log("子弹数量："+bullets.length);
            this.shootLastTime=new  Date().getTime();
        }
    }
    /**
     * 天空的业务对象
     * */
    var Sky=function(config){
        this.bg=config.image;
        this.width=config.width;
        this.height=config.height;
        this.speed=1000/config.speed;
        this.x1=0;
        this.y1=0;
        this.x2=0;
        this.y2=-this.height;
        this.lastTime=0; //上一次执行动作时间的毫秒数

        /**
         * 移动背景纵坐标
         * */
//        this.step=function(){
//            //判断是否到达天空移动的时间
//            //获取当前时间的毫秒数
//            var currentTime=new Date().getTime();
//            if(currentTime-this.lastTime>=this.speed){
//                this.y1++;
//                this.y2++;
//                this.lastTime=new Date().getTime();
//            }
//            //判断y1,y2是否超出范围
//            if(this.y1>=this.height){
//                this.y1=-this.height;
//            }
//            if(this.y2>=this.height){
//                this.y2=-this.height;
//            }
//        }
        /**
         * 绘制天空图像
         * */
//        this.paint=function(ctx){
//            ctx.drawImage(this.bg,this.x1,this.y1);
//            ctx.drawImage(this.bg,this.x2,this.y2);
//        }
    }
    Sky.prototype.step=function(){

            //判断是否到达天空移动的时间
            //获取当前时间的毫秒数
           var currentTime=new Date().getTime();
            if(currentTime-this.lastTime>=this.speed){
                this.y1++;
                this.y2++;
                this.lastTime=new Date().getTime();
               // console.log(this.y1+" : "+this.y2);
            }
            //判断y1,y2是否超出范围
            if(this.y1>=this.height){
                this.y1=-this.height;
            }
            if(this.y2>=this.height){
                this.y2=-this.height;
            }

    }
    Sky.prototype.paint=function(ctx){
        ctx.drawImage(this.bg,this.x1,this.y1);
        ctx.drawImage(this.bg,this.x2,this.y2);
    }
    /**
     * 加载业务对象
     * config：表示加载的数据对象
     * */
    var Loading=function(config){
        this.speed=1000/config.speed;
        this.lastTime=0;
        this.frame=null;
        this.frameIndex=0;
        //更换loading图像
        this.step=function(){
            var currentTime=new Date().getTime();
            if(currentTime-this.lastTime>this.speed){
                //获取不同的图像config.frames中的元素给frame
                this.frame=config.frames[this.frameIndex];
                this.frameIndex++;
                if(this.frameIndex>=4){
                    //更新状态
                    state=RUNNING;
                }
                this.lastTime=new Date().getTime();
            }
        }
        /**
         * 绘制不同的图像到canvas上
         * */
        this.paint=function(ctx){
            ctx.drawImage(this.frame,config.x,config.y);
        }
    }

    //创建业务对象
    var sky=new Sky(SKY);
    var loading=new Loading(LOADING);
    var hero=new Hero(HERO);

    /**
     * 绘制各个组件
     * */
    function paintComponent(){
        //绘制子弹
        for(var i=0;i<bullets.length;i++){
            var bullet=bullets[i];
            bullet.paint();
        }
        //将绘制hero的方法移动至此
        hero.paint();
        ctx.font="20px 微软雅黑";
        ctx.fillText("SCORE:"+score,10,20);
        ctx.fillText("LIFE:"+life,400,20);
    }

    /**
     * 让所有的子弹 动起来（更新y坐标）
     * */
    function stepComponent(){
        for(var i=0;i<bullets.length;i++){
            bullets[i].move();
        }
    }

    //定时器，固定刷新频率为 1000/100 =10ms
    setInterval(function(){
        switch (state){
        case START:
            //天空在移动
            sky.step();
            sky.paint(ctx);
            //绘制copyright
            var x=(WIDTH-copyright.naturalWidth)/2;
            var y=(HEIGHT-copyright.naturalHeight)/2;
            ctx.drawImage(copyright,x,y);
            break;
            case STARTING:
                //准备开始
                sky.step();
                sky.paint(ctx);
                loading.step();
                loading.paint(ctx);
                break;
            case RUNNING:
                //游戏进行
                sky.step();
                sky.paint(ctx);

                hero.step();
                hero.paint(ctx);
                hero.shoot();

                stepComponent();
                //绘制所有的组件
                paintComponent();
                break;
            case PAUSE:
                //暂停
                sky.step();
                sky.paint(ctx);

                paintComponent();
                ctx.drawImage(pause,(WIDTH-pause.width)/2,(HEIGHT-pause.height)/2);
                break;
            case GAME_OVER:
                break;
        }
    },1000/100)








































































</script>
</body>
</html>